package cn.itsource.user.service.impl;

import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.WxUser;
import cn.itsource.user.domain.vo.UserVo;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.mapper.WxUserMapper;
import cn.itsource.user.service.IWxUserService;
import cn.itsource.utils.AjaxResult;
import cn.itsource.utils.HttpClientUtils;
import cn.itsource.utils.WXContents;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WxUserServiceImpl extends BaseServiceImpl<WxUser> implements IWxUserService {

    @Autowired
    private WxUserMapper mapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public AjaxResult getAccessToken(String code) {
        //1.根据code APPID 秘钥  发送请求  获取access_token
        //组装 请求的URL
        String url = WXContents.ACCESS_TOKEN.replace("CODE", code);
        //2.发送请求 获取 access_token
        String resp = HttpClientUtils.httpGet(url);
        /*{
            "access_token":"47_hLbaSJ08xWVtfhvvvK7l2_i5-hVvlU6SGi9o7fTcmCoJ3Hlfqmvy_noqCqZW1sQpz_Bzx220j73IPg8w5KBIyETmX_gBAOJ7IxMbgCwDViI",
            "expires_in":7200,
            "refresh_token":"47_LlHAl_ptD-5N_1yom8DgsQtCdWZWW-bGGuer6Y1rgfqzOc64XKOM8bAFwZe9yrvzuacH-iLmOZxMQ52RVg0Vo-7zFrxdd0O_DPT6Eh-NDYY",
            "openid":"oa9wA0_clwVQ6uUbZgkQ3MgzLnAg",
            "scope":"snsapi_login",
            "unionid":"ovnCWwwJ3S9h_pJ4Rcz_HecQ93BI"
            }
            返回值  openid 是用户的唯一标识
            1.根据用户的openid 检测用户 是不是第一次使用微信登录
               1.1 如果不是第一次使用 跳转到首页  已经登录的状态
                1.2 查询关联 用户数据 并且登录
            2.如果第一次使用，跳转到绑定页面



         */
        // System.out.println(resp);
        //1.解析JSON字符串，获取里面的数据  把json转化为 map对象 --------使用工具 fastjson
        JSONObject jsonObject = JSONObject.parseObject(resp);
        //获取里面的access_token
        String access_token = jsonObject.getString("access_token");
        //获取里面的openid
        String openid = jsonObject.getString("openid");
        //2.获取里面的openid,根据openid 查询t_wxuser 用户是否第一次登录系统
        WxUser wxUser = mapper.loadByOpenid(openid);
        //3.如果t_wxuser 和 关联的user不为空，直接【免密登录】
        if (wxUser!=null && wxUser.getUser()!=null){//直接【免密登录】
            if (wxUser.getUser().getState()==1){
               /* //获取当当前的登录用户
                User login = wxUser.getUser();
                //生成一个token 当前的登录用户组合一对数据
                //token 要求：唯一性
                String token = UUID.randomUUID().toString();
                //存储在redis里面
                redisTemplate.opsForValue().set(token, login, 30, TimeUnit.MINUTES);
                Map<String,Object> map = new HashMap<>();
                map.put("token", token);
                //清除数据里面的敏感数据
                map.put("user", login);
                //返回token数据 返回当前的额登录用户
                return AjaxResult.me().setResultObj(map);*/
                return login(wxUser.getUser());
            }else {
                return AjaxResult.me().setSuccess(false).setMessage("用户账号数据异常,请联系客服");
            }
        }else { //4.如果t_wxuser 为空 或者 关联的user为空 ，页面的跳转，跳转到绑定页面



            String bindurl="/binder.html?openid="+openid+"&access_token="+access_token;
            return AjaxResult.me().setSuccess(false).setMessage("binder").setResultObj(bindurl);
        }

    }

    @Autowired
    private UserMapper userMapper;
    @Override
    @Transactional
    public AjaxResult binder(UserVo userVo) {
        // userVo [phone:111 ,code:000]
        //验证码是否和redis里面存储的一致
        String redisInCode = (String) redisTemplate.opsForValue().get("BINDER:"+userVo.getPhone());
        if (redisInCode==null){
            throw new RuntimeException("验证码已经过期");
        }else {
            String code= redisInCode.split(":")[0];
            if (!userVo.getCode().equals(code)){
                throw  new RuntimeException("验证码输入不正确");
            }
        }

        //获取微信的用户数据，生成一个WxUser对象 ，和User绑定，并且保存数据
        String url= WXContents.USERINFO_URL
                .replace("ACCESS_TOKEN", userVo.getToken())
                .replace("OPENID", userVo.getOpenid());
        //发送请求获取数据
        String userinfo = HttpClientUtils.httpGet(url);
        //解析字符串
        JSONObject jsonObject = JSONObject.parseObject(userinfo);

        //根据手机判断用户是否存在
        User user = userMapper.loadByPhone(userVo.getPhone());
        if (user==null){//创建一个User 并保存
            user=new User();
            user.setPhone(userVo.getPhone());
            user.setUsername(jsonObject.getString("nickname"));
            user.setHeadImg(jsonObject.getString("headimgurl"));
            user.setCreatetime(new Date());
            user.setState(1);
            userMapper.save(user);//需要返回user的主键
        }

        //生成微信的用户数据
        WxUser wxUser = new WxUser();
        wxUser.setOpenid(jsonObject.getString("openid"));
        wxUser.setNickname(jsonObject.getString("nickname"));
        wxUser.setHeadimgurl(jsonObject.getString("headimgurl"));
        wxUser.setSex(jsonObject.getInteger("sex"));
        wxUser.setUnionid(jsonObject.getString("unionid"));
        wxUser.setAddress(jsonObject.getString("country")+" " +jsonObject.getString("province")+" "+jsonObject.getString("city"));
        //和用户绑定
        wxUser.setUser(user);
        //保存到数据库
        mapper.save(wxUser);

        return login(user);
    }



    private AjaxResult login(User user){

        String token = UUID.randomUUID().toString();
        //存储在redis里面
        redisTemplate.opsForValue().set(token, user, 30, TimeUnit.MINUTES);
        Map<String,Object> map = new HashMap<>();
        map.put("token", token);
        //清除数据里面的敏感数据
        user.setState(null);
        user.setPassword("");
        user.setSalt("");

        map.put("user", user);
        //返回token数据 返回当前的额登录用户
        return AjaxResult.me().setResultObj(map);

    }
}
